package com.itheima.reggie.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.reggie.common.CustomException;
import com.itheima.reggie.common.R;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.entity.Category;
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.entity.DishFlavor;
import com.itheima.reggie.entity.Setmeal;
import com.itheima.reggie.service.CategoryService;
import com.itheima.reggie.service.DishFlavorService;
import com.itheima.reggie.service.DishService;
import javafx.animation.PauseTransition;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 菜品管理 前端控制器
 * </p>
 *
 * @author 宋
 * @since 2022-06-06
 */
@Slf4j
@RestController
@RequestMapping("/dish")
public class DishController {

    @Autowired
    private DishService dishService;
    @Autowired
    private DishFlavorService dishFlavor;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private RedisTemplate redisTemplate;


    /**
     * 新建菜品
     * Request URL: http://127.0.0.1:8080/dish
     * Request Method: POST
     */
    @PostMapping
    public R<String> save(@RequestBody DishDto dishDto) {
        //1.添加dish的基础字段
        // TODO 1. 现在保存dish到数据库  会自动生成雪花id  ,多余的字段会忽略掉
        dishService.save(dishDto);

        //只要新建菜品之后就清空 所有 -->>redis数据缓存
        Set keys = redisTemplate.keys("dish_*");
        redisTemplate.delete(keys);

        //2.拿到这个菜品的id
        // TODO  2. 自动生成的id会自动赋值到dishDto-->  把主键id 再赋值到dishDto   因为dishDto继承了Dish,会有主键id
        Long dishid = dishDto.getId();

        //3.dishid赋值给idshFlavor
        List<DishFlavor> flavors = dishDto.getFlavors();
        for (DishFlavor flavor : flavors) {
            flavor.setDishId(dishid);    // TODO 3. 再赋值给每个菜品口味 --> 再把菜品口味插入到对应的表就可以了
            dishFlavor.save(flavor);
        }
        return R.success("添加菜品成功.");
    }

    /**
     * 修改后保存菜品
     * Request URL: http://127.0.0.1:8080/dish
     * Request Method: PUT
     */
    @PutMapping
    public R<String> update(@RequestBody DishDto dishDto) {
        //三张表也要更新 dish菜品/口味/菜品分类
        Long id = dishDto.getId();
        //更新口味表 (要先删除旧口味)
        LambdaQueryWrapper<DishFlavor> queryWrapper01 = new LambdaQueryWrapper<>();
        queryWrapper01.eq(DishFlavor::getDishId, id);
        dishFlavor.remove(queryWrapper01);
        List<DishFlavor> flavors = dishDto.getFlavors();
        for (DishFlavor flavor : flavors) {
            flavor.setDishId(id);
            dishFlavor.save(flavor);
        }
        //更新菜品分类
        String categoryName = dishDto.getCategoryName();  //菜品分类的名字
        //条件构造器
        LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Category::getName, categoryName);
        Category category = categoryService.getOne(queryWrapper);
        //根据名字查出这个对象 并得到id
        Long categoryId = category.getId();
        //再更新dish表中对应的categoryId
        dishDto.setCategoryId(categoryId);

        //更新dish
        dishService.updateById(dishDto);

        //只要新建菜品之后就清空 所有 -->>redis数据缓存
        Set keys = redisTemplate.keys("dish_*");
        redisTemplate.delete(keys);


        return R.success("修改成功");
    }

    /**
     * 修改状态
     * Request URL: http://127.0.0.1:8080/dish/status/0?ids=1397849739276890114
     * Request Method: POST
     */
    @PostMapping("/status/{status}")
    public R<String> update(@PathVariable Integer status, @RequestParam List ids) {
        //更改售卖状态
      /* LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Dish::getId,ids).*/
        List<Dish> list = dishService.listByIds(ids);
        for (Dish dish : list) {
            dish.setStatus(status);
        }
        dishService.updateBatchById(list);

        //只要新建菜品之后就清空 所有 -->>redis数据缓存
        Set keys = redisTemplate.keys("dish_*");
        redisTemplate.delete(keys);

        return R.success("售卖状态修改成功");
    }


    /**
     * 删除菜品
     * Request URL: http://127.0.0.1:8080/dish?ids=1397849739276890114
     * Request Method: DELETE
     */
    @DeleteMapping
    public R<String> delete(@RequestParam List ids) {
        //有批量删除 是个集合
        //判断 停售状态才能删除  -->> 拿到所有要删除的对象 一个一个判断
        List<Dish> list = dishService.listByIds(ids);
        for (Dish dish : list) {
            if (dish.getStatus() == 1) {
                //有在售状态的菜品 不能删除 -->> 抛出业务异常
                throw new CustomException("有在售的菜品,不能删除");
            }
        }
        dishService.removeByIds(ids);
        //dishService.getById(ids);

        //只要新建菜品之后就清空 所有 -->>redis数据缓存
        Set keys = redisTemplate.keys("dish_*");
        redisTemplate.delete(keys);


        //TODO 没写了
        return R.success("删除成功");
    }


    //客户端

    /**
     * 对应菜品分类 -->> 回显菜品
     * Request URL: http://127.0.0.1:8888/dish/list?categoryId=1397844263642378242&status=1
     * Request Method: GET
     */
    @GetMapping("/list")
    public R<List<Dish>> list(@RequestParam Map map) {

        List<Dish> list =null;

        // 分页查询缓存redis数据库
        // 1)先构造缓存的key
        String key = "dish_" + map.get("categoryId") + "_" + map.get("status");
        // 2)通过key查询缓存
        list = (List<Dish>) redisTemplate.opsForValue().get(key);
        // 3)如果查询到数据直接返回
        if (list!=null){
            return R.success(list);
        }
        // 4)查询不到-查询mysql数据库


        System.out.println(111);
        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
        //用户端 回显需要带上口味
        //拿到所有菜品id -->> 再到菜品口味表里查对应的口味
        queryWrapper.eq(Dish::getCategoryId, map.get("categoryId")).eq(map.get("status").equals(null),
                Dish::getStatus,
                map.get("status"));
        list = dishService.list(queryWrapper);

        List<Long> dishIds = list.stream().map(dish -> dish.getId()).collect(Collectors.toList());
        //2)通过菜品的id集合查询出对应的所有口味信息  //TODO   SQL:select * from dish_flavor where dish_id in ('','');
        LambdaQueryWrapper<DishFlavor> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.in(DishFlavor::getDishId, dishIds);
        List<DishFlavor> list1 = dishFlavor.list(queryWrapper1);
        for (Dish dish : list) {
            Long id = dish.getId();
            List<DishFlavor> collect =
                    list1.stream().filter(dishFlavor1 -> id.equals(dishFlavor1.getDishId())).collect(Collectors.toList());
            dish.setFlavors(collect);
        }
        redisTemplate.opsForValue().set(key,list);      // 5)把数据放入缓存
        return R.success(list);
    }


    /**
     * 修改菜品
     * Request URL: http://127.0.0.1:8080/dish/1397849739276890114
     * Request Method: GET
     */
    @GetMapping("/{id}")
    public R<Dish> updata(@PathVariable Long id) {
        DishDto dishDto = new DishDto();
        //回显
        Dish dish = dishService.getById(id);
        String name = categoryService.getById(dish.getCategoryId()).getName();  //加入菜品类型
        dish.setCategoryName(name);
        BeanUtils.copyProperties(dish, dishDto);

        //查询对应口味  条件构造器
        LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DishFlavor::getDishId, id);
        List<DishFlavor> list = dishFlavor.list(queryWrapper);
        dishDto.setFlavors(list);

        return R.success(dishDto);
    }


    /**
     * 菜品管理分页查询
     * Request URL: http://127.0.0.1:8080/dish/page?page=1&pageSize=10
     * Request Method: GET
     * page: 1 & pageSize: 10
     */
    @GetMapping("/page")
    public R<Page> page(Integer page, Integer pageSize, String name) {

        //1.条件构造器    select * from  Dish
        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper();
        //判断是否传入了name 进行模糊查询
        queryWrapper.like(StringUtils.isNotEmpty(name), Dish::getName, name);
        //2.分页构造器
        Page<Dish> objectPage = new Page<>(page, pageSize);

        //3.查询  //select * from  Dish   where name like  '%%'  limit  0,10
        dishService.page(objectPage, queryWrapper);

        // 4--> 再查菜品表里对应的菜品id  -->> 查出菜品表里出现的categoryId  -->>  创建categoryId 和 categoryName 的对应关系  -->>  再一一赋值给dish
        List<Dish> records = objectPage.getRecords();
        HashSet<Long> hashSet = new HashSet<>();
        HashMap<Long, String> map = new HashMap<>();
        for (Dish record : records) {
            Long categoryId = record.getCategoryId();
            hashSet.add(categoryId);
        }

        //4.1 查询到id的集合
        List<Category> categories = categoryService.listByIds(hashSet);
        //4.2 创建categoryId 和 categoryName 的对应关系
        for (Category category : categories) {
            map.put(category.getId(), category.getName());
        }

        /* for (Long categoryId : hashSet) {
            String name1 = categoryService.getById(categoryId).getName();
            map.put(categoryId, name1);
        }*/
        //4.3  再一一赋值给dish里的冗余字段
        for (Dish dish : records) {
            String s = map.get(dish.getCategoryId());
            dish.setCategoryName(s);
        }

        objectPage.setRecords(records);
        return R.success(objectPage);
    }

    //----------------

}

